package com.example.activiti.utils;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author Mr.yuan
 * @version v1.0
 * @date 2019/11/8 16:20
 **/
public class WorkflowUtils {

    private static final String DIRECTORY = System.getProperty("user.dir") + File.separator + "bpmn" + File.separator;

    /**
     * 导出图片文件到硬盘
     *
     * @return 文件的全路径
     */
    public static void exportDiagramToFile(RepositoryService repositoryService, ProcessDefinition processDefinition) throws IOException {
        String diagramResourceName = processDefinition.getDiagramResourceName();
        String diagramPath = diagramResourceName.substring(diagramResourceName.indexOf("."));
        String parentPath = DIRECTORY + diagramPath;
        String path = parentPath + File.separator + diagramResourceName;
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
            file.createNewFile();
        }
        InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
        byte[] b = new byte[resourceAsStream.available()];
        resourceAsStream.read(b, 0, b.length);
        FileUtils.writeByteArrayToFile(file, b);
        resourceAsStream.close();

        path = parentPath + File.separator + processDefinition.getResourceName();
        file = new File(path);
        if (!file.exists()) {
            file.createNewFile();
        }
        resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
        b = new byte[resourceAsStream.available()];
        resourceAsStream.read(b, 0, b.length);
        FileUtils.writeByteArrayToFile(file, b);
        resourceAsStream.close();
    }

    /**
     * @param filePaths        需要压缩的文件地址列表（绝对路径）
     * @param zipPackage       需要压缩到哪个zip文件（无需创建这样一个zip，只需要指定一个全路径）
     * @param keepDirStructure 压缩后目录是否保持原目录结构
     * @return int  压缩成功的文件个数
     * @throws IOException 异常
     */
    public static int compress(List<String> filePaths, String zipPackage, Boolean keepDirStructure) throws IOException {

        String packagePath = mkdirs(zipPackage);
        File zipFile = createNewFile(packagePath, zipPackage + ".zip");
        //记录压缩了几个文件？
        int fileCount = 0;
        try {
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
            for (String relativePath : filePaths) {
                if (StringUtils.isBlank(relativePath)) {
                    continue;
                }
                //绝对路径找到file
                File sourceFile = new File(relativePath);
                if (!sourceFile.exists()) {
                    continue;
                }
                FileInputStream fis = new FileInputStream(sourceFile);
                if (keepDirStructure != null && keepDirStructure) {
                    //保持目录结构
                    zos.putNextEntry(new ZipEntry(relativePath));
                } else {
                    //直接放到压缩包的根目录
                    zos.putNextEntry(new ZipEntry(sourceFile.getName()));
                }
                System.out.println("压缩当前文件：" + sourceFile.getName());
                int len;
                byte[] buf = new byte[1024];
                while ((len = fis.read(buf)) > 0) {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                fis.close();
                fileCount++;
            }
            zos.close();
            System.out.println("压缩完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileCount;
    }

    public static void main(String[] args) throws IOException {
        List<String> sourceFilePaths = new ArrayList<String>();
        sourceFilePaths.add("C:\\Users\\ThinkPad\\Downloads\\leave-dynamic-from.bpmn.bpmn20.xml");
        sourceFilePaths.add("C:\\Users\\ThinkPad\\Downloads\\leave-dynamic-from.bpmn.leave-dynamic-from.png");
        //指定打包到哪个zip（绝对路径）
        String zipTempFilePath = "C:\\Users\\ThinkPad\\Downloads\\test.zip";
        //调用压缩
        int s = compress(sourceFilePaths, zipTempFilePath, false);
        System.out.println("成功压缩" + s + "个文件");
    }

    public static String saveResource(InputStream resourceInputStream, String resourceName) throws IOException {
        byte[] bytes = new byte[resourceInputStream.available()];
        int size = resourceInputStream.read(bytes, 0, bytes.length);
        String packageName = resourceName.substring(0, resourceName.indexOf("."));
        String packagePath = mkdirs(packageName);
        File file = createNewFile(packagePath, resourceName);
        FileUtils.writeByteArrayToFile(file, bytes);
        System.out.println("当前文件大小：" + size);
        return file.getAbsolutePath();
    }

    private static String mkdirs(String path) {
        boolean success = true;
        File file = new File(DIRECTORY + File.separator + path);
        if (!file.exists()) {
            success = file.mkdirs();
        }
        if (success) {
            return file.getPath();
        }
        throw new RuntimeException("创建流程图文件夹失败");
    }

    private static File createNewFile(String packagePath, String fileName) throws IOException {
        boolean success = true;
        File file = new File(packagePath + File.separator + fileName);
        if (!file.exists()) {
            success = file.createNewFile();
        }
        if (success) {
            return file;
        }
        throw new RuntimeException("创建流程图文件夹失败");
    }
}
